package leecode.dp;

/**
 * @Classname MatrixChainOrder
 * @Description TODO
 * @Date 2021/8/4 15:24
 * @Created by Alberthch
 *
 * 矩阵链乘，动态规划
 */
public class MatrixChainOrder {
    public static int[][] matrixChainOrder(int[] p) {
        // 矩阵序列长度为l，n=l+1
        int n = p.length;
        int[][] m = new int[n][n];
        int[][] s = new int[n][n];

        for (int i = 0; i < n; i++) {
            m[i][i] = 0;
        }

        int j;
        int temp;

        for (int l = 2; l < n; l++) {
            for (int i = 1; i < n-l+1; i++) {
                j = i+l-1;
                m[i][j] = Integer.MAX_VALUE;
                for (int k = i; k < j; k++) {
                    temp = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                    if (temp < m[i][j]) {
                        m[i][j] = temp;
                        s[i][j] = k;
                    }
                }

            }

        }


        printArray(m);
        System.out.println();
        printArray(s);

        return s;

    }

    // 规范打印二维数组的方法
    public static void printArray(int[][] arr){
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[0].length; j++) {
                if (j == arr[0].length-1) {
                    if (i == arr.length-1) {
                        System.out.println(arr[i][j] + "]");
                    } else {
                        System.out.println(arr[i][j]);
                    }
                } else {
                    System.out.print(arr[i][j]+",");
                }
            }
        }

    }

    // 构造最优化括号方案
    public static void printOptimalParens(int[][] s,int i,int j) {
        if (i == j) {
            System.out.print("A"+i);
        } else {
            System.out.print("(");
            printOptimalParens(s,i,s[i][j]);
            printOptimalParens(s,s[i][j] + 1,j);
            System.out.print(")");
        }
    }

    public static void main(String[] args) {
        int[] p = new int[]{30,35,15,5,10,20,25};
        int[][] s = matrixChainOrder(p);
        printOptimalParens(s,1,p.length-1);

    }
}
